#include "can.h"
#include "delay.h"
#include "User.h"
// CAN初始化
// tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
// tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
// tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
// brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
// 波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
// mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
// Fpclk1的时钟在初始化的时候设置为42M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);
// 则波特率为:42M/((6+7+1)*6)=500Kbps
// 返回值:0,初始化OK;
//     其他,初始化失败;
//
void can_receive_setting1(u32 id, u8 formate, u8 fliternub, u8 Filter_FIFO0)
{
	CAN_FilterInitTypeDef CAN_FilterInitStructure;
	CAN_FilterInitStructure.CAN_FilterNumber = fliternub; // 过滤器0
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 32位
	if (formate == CAN_Id_Standard)
	{
		CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)id << 21) & 0xffff0000) >> 16;
		CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)id << 21) | CAN_ID_STD | CAN_RTR_DATA) & 0xffff;
		CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
	}
	else
	{
		CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)id << 3) & 0xFFFF0000) >> 16;
		CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)id << 3) | CAN_ID_EXT) & 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
	}
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = Filter_FIFO0; // 过滤器0关联到FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;			 // 激活过滤器0
	CAN_FilterInit(&CAN_FilterInitStructure);						 // 滤波器初始化
}
//
void can_receive_setting2(u32 id, u8 formate, u8 fliternub, u8 Filter_FIFO0)
{
	CAN_FilterInitTypeDef CAN_FilterInitStructure;
	CAN_FilterInitStructure.CAN_FilterNumber = fliternub; // 过滤器0
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 32位
	if (formate == CAN_Id_Standard)
	{
		CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)id << 21) & 0xffff0000) >> 16;
		CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)id << 21) | CAN_ID_STD | CAN_RTR_DATA) & 0xffff;
		CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
	}
	else
	{
		CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)id << 3) & 0xFFFF0000) >> 16;
		CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)id << 3) | CAN_ID_EXT) & 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
		CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
	}
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = Filter_FIFO0; // 过滤器0关联到FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;			 // 激活过滤器0
	CAN_FilterInit(&CAN_FilterInitStructure);						 // 滤波器初始化
}
//
u8 CAN1_Mode_Init(u16 baud_rate)
{

	GPIO_InitTypeDef GPIO_InitStructure;
	CAN_InitTypeDef CAN_InitStructure;
	//	CAN_FilterInitTypeDef  CAN_FilterInitStructure,CAN_FilterInitStructure1;
	NVIC_InitTypeDef NVIC_InitStructure;
	// 使能相关时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能PORTA时钟

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // 使能CAN1时钟

	// 初始化GPIO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;	   // 复用功能
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	   // 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;	   // 上拉
	GPIO_Init(GPIOA, &GPIO_InitStructure);			   // 初始化PA11,PA12

	// 引脚复用映射配置
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1); // GPIOA11复用为CAN1
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); // GPIOA12复用为CAN1

	// CAN单元设置
	CAN_InitStructure.CAN_TTCM = DISABLE;		  // 非时间触发通信模式
	CAN_InitStructure.CAN_ABOM = DISABLE;		  // 软件自动离线管理
	CAN_InitStructure.CAN_AWUM = DISABLE;		  // 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
	CAN_InitStructure.CAN_NART = DISABLE;		  // 禁止报文自动传送
	CAN_InitStructure.CAN_RFLM = DISABLE;		  // 报文不锁定,新的覆盖旧的
	CAN_InitStructure.CAN_TXFP = DISABLE;		  // 优先级由报文标识符决定
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // 模式设置
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;	  // 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
	CAN_InitStructure.CAN_BS1 = CAN_BS2_6tq;	  // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
	CAN_InitStructure.CAN_BS2 = CAN_BS1_7tq;	  // Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
	if (baud_rate == 500)
	{
		CAN_InitStructure.CAN_BS1 = CAN_BS2_6tq; // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
		CAN_InitStructure.CAN_BS2 = CAN_BS1_7tq; // Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
		CAN_InitStructure.CAN_Prescaler = 6;	 // 分频系数(Fdiv)为brp+1
	}
	else if (baud_rate == 125)
	{
		CAN_InitStructure.CAN_BS1 = CAN_BS2_6tq; // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
		CAN_InitStructure.CAN_BS2 = CAN_BS1_7tq; // Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
		CAN_InitStructure.CAN_Prescaler = 24;	 // 分频系数(Fdiv)为brp+1
	}
	else
	{
		CAN_InitStructure.CAN_BS1 = CAN_BS2_6tq; // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
		CAN_InitStructure.CAN_BS2 = CAN_BS1_7tq; // Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
		CAN_InitStructure.CAN_Prescaler = 12;	 // 分频系数(Fdiv)为brp+1
	}
	CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
										// ================================FLITER========================================
	CAN1_RX_Init();
	//=================================================================================
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // FIFO0消息挂号中断允许.
	NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		  // 次优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	return 0;
}

u8 CAN2_Mode_Init(u16 baud_rate)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	CAN_InitTypeDef CAN_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	// 使能相关时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 使能PORTA时钟

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); // 使能CAN2时钟

	// 初始化GPIO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;	   // 复用功能
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;	   // 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;	   // 上拉
	GPIO_Init(GPIOB, &GPIO_InitStructure);			   // 初始化PA11,PA12

	// 引脚复用映射配置
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN1); // GPIOB12复用为CAN1
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN1); // GPIOB13复用为CAN1

	// CAN单元设置
	CAN_InitStructure.CAN_TTCM = DISABLE;		  // 非时间触发通信模式
	CAN_InitStructure.CAN_ABOM = DISABLE;		  // 软件自动离线管理
	CAN_InitStructure.CAN_AWUM = DISABLE;		  // 睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
	CAN_InitStructure.CAN_NART = DISABLE;		  // 禁止报文自动传送
	CAN_InitStructure.CAN_RFLM = DISABLE;		  // 报文不锁定,新的覆盖旧的
	CAN_InitStructure.CAN_TXFP = DISABLE;		  // 优先级由报文标识符决定
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // 模式设置
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;	  // 重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
	CAN_InitStructure.CAN_BS1 = CAN_BS2_6tq;	  // Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
	CAN_InitStructure.CAN_BS2 = CAN_BS1_7tq;	  // Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
	if (baud_rate == 500)
		CAN_InitStructure.CAN_Prescaler = 6; // 分频系数(Fdiv)为brp+1
	else if (baud_rate == 125)
		CAN_InitStructure.CAN_Prescaler = 24; // 分频系数(Fdiv)为brp+1
	else
		CAN_InitStructure.CAN_Prescaler = 12; // 分频系数(Fdiv)为brp+1
	CAN_Init(CAN2, &CAN_InitStructure);		  // 初始化CAN2
											  // ================================FLITER========================================
	CAN2_RX_Init();
	//=================================================================================
	CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE); // FIFO0消息挂号中断允许.
	NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		  // 次优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	return 0;
}
#if CAN1_RX_INT_ENABLE // 使能RX0中断
// 中断服务函数
void CAN1_RX0_IRQHandler(void)
{
	KOP_CAN1_Event();
}
#endif

#if CAN2_RX_INT_ENABLE // 使能RX0中断
void CAN2_RX0_IRQHandler(void)
{
	KOP_CAN2_Event();
}
#endif
// can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
// len:数据长度(最大为8)
// msg:数据指针,最大为8个字节.
// 返回值:0,成功;
//		 其他,失败;
u8 CAN1_Send_Msg(u8 *msg, u8 len)
{
	u8 mbox;
	u16 i = 0;
	CanTxMsg TxMessage;
	TxMessage.StdId = 0x12; // 标准标识符为0
	TxMessage.ExtId = 0;	// 设置扩展标示符（29位）
	TxMessage.IDE = 0;		// 使用扩展标识符
	TxMessage.RTR = 0;		// 消息类型为数据帧，一帧8位
	TxMessage.DLC = len;	// 发送两帧信息
	for (i = 0; i < len; i++)
		TxMessage.Data[i] = msg[i]; // 第一帧信息
	mbox = CAN_Transmit(CAN1, &TxMessage);
	i = 0;
	while ((CAN_TransmitStatus(CAN1, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF))
		i++; // 等待发送结束
	if (i >= 0XFFF)
		return 1;
	return 0;
}
// can口接收数据查询
// buf:数据缓存区;
// 返回值:0,无数据被收到;
//		 其他,接收的数据长度;
u8 CAN1_Receive_Msg(u8 *buf)
{
	u32 i;
	CanRxMsg RxMessage;
	if (CAN_MessagePending(CAN1, CAN_FIFO0) == 0)
		return 0;							  // 没有接收到数据,直接退出
	CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); // 读取数据
	for (i = 0; i < RxMessage.DLC; i++)
		buf[i] = RxMessage.Data[i];
	return RxMessage.DLC;
}

//--------------------------CAN PART OF FL----------------------------------
u8 CAN_Send_Msg_FC(u8 channel_num, u32 id, u8 formate, u8 len, u8 *msg)
{
	u8 mbox;
	u16 i = 0;
	CanTxMsg TxMessage;
	TxMessage.StdId = id;	 // 标准标识符为0
	TxMessage.ExtId = id;	 // 设置扩展标示符（29位）
	TxMessage.IDE = formate; // 使用扩展标识符
	TxMessage.RTR = 0;		 // 消息类型为数据帧，一帧8位
	TxMessage.DLC = len;	 // 发送两帧信息
	for (i = 0; i < len; i++)
		TxMessage.Data[i] = msg[i]; // 第一帧信息
	if (channel_num == 1)
	{
		mbox = CAN_Transmit(CAN1, &TxMessage);
		i = 0;
		while ((CAN_TransmitStatus(CAN1, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF))
			i++; // 等待发送结束
	}
	else
	{
		mbox = CAN_Transmit(CAN2, &TxMessage);
		i = 0;
		while ((CAN_TransmitStatus(CAN2, mbox) == CAN_TxStatus_Failed) && (i < 0XFFF))
			i++; // 等待发送结束
	}
	if (i >= 0XFFF)
		return 1;
	return 0;
}
